#include <bits/stdc++.h>
using namespace std;
const int N = 100000 + 10;
const int INF = 0x3f3f3f3f;
// Treap 模板
struct node {
  int l, r,  // 左右儿子指针
      key,  // 满足堆性质的 key，a[p].key > max(a[a[p].l].key, a[a[p].r].key)
            // 即 p 节点的 key 大于任意一个子节点的 key
      val;   // 满足BST性质的 val
  int cnt,   // 计数，记录有多少个重复的 val 值
      size;  // 本身、左子树、右子树总大小
} a[N];
int root, idx;
/**
 * @brief 计算 p 节点的 size
 **/
void update(int p) { a[p].size = a[a[p].l].size + a[a[p].r].size + a[p].cnt; }
/**
 * @brief Get the node object
 **/
int get_node(int val) {
  a[++idx] = {0, 0, rand(), val, 1, 1};
  return idx;
}
/**
 * @brief 右旋，将 p 的左节点提上来
 **/
void zig(int& p) {
  int q = a[p].l;
  a[p].l = a[q].r, a[q].r = p, p = q;
  update(a[p].r),  // 从下向上 update, a[p].r 是原来被放下去的 p
      update(p);
}
/**
 * @brief 左旋，将 p 的右节点提上来
 **/
void zag(int &p) {
  int q = a[p].r;
  a[p].r = a[q].l, a[q].l = p, p = q;
  update(a[p].l),  // a[p].l 是被放下去的原来的 p
      update(p);
}
/**
 * @brief 建树，插入一个 INF 和一个 -INF
 *
 **/
void build() {
  root = get_node(-INF);
  a[root].r = get_node(INF);
  update(root);
}
/**
 * @brief 在以 p 为根节点的树中插入一个 val 值; 若 p 为空，则将 p
 * 赋值为一个新节点
 *
 * @param p
 * @param val
 **/
void insert(int& p, int val) {
  if (p == 0)
    p = get_node(val);
  else {
    if (a[p].val == val) {
      a[p].cnt++;
    } else {
      if (val < a[p].val) {
        insert(a[p].l, val);
        if (a[p].key < a[a[p].l].key) zig(p);
      } else if (val > a[p].val) {
        insert(a[p].r, val);
        if (a[p].key < a[a[p].r].key) zag(p);
      }
    }
  }
  update(p);
}
/**
 * @brief 在以 p 为根节点的子树中删除一个 val 值
 **/
void remove(int& p, int val) {
  if (p == 0) return;
  if (a[p].val == val) {  // 检索到，准备删除
    if (a[p].cnt > 1) {   // 多个，拿掉一个就好
      a[p].cnt--;
    } else {                   // 独苗一根
      if (a[p].l || a[p].r) {  // 不是叶子
        // 如果右节点空，一定要把左儿子提上来，把 p 往叶子上放
        if (a[p].r == 0) {
          zig(p);
          remove(a[p].r, val);
        }
        // 如果左节点空，一定要把右儿子提上来
        else if (a[p].l == 0) {
          zag(p);
          remove(a[p].l, val);  // 要删除的值到了左子树上，递归删除
        }
        // 如果儿女双全，那么考虑 key 的堆性质
        else if (a[a[p].l].key > a[a[p].r].key) {
          zig(p);
          remove(a[p].r, val);
        } else if (a[a[p].l].key <= a[a[p].r].key) {
          zag(p);
          remove(a[p].l, val);
        } else
          assert(false);
      } else {  // 是叶子，直接搞成空节点
        p = 0;
      }
    }
  } else {  // 未检索到，递归检索，题目保证有解
    val < a[p].val ? remove(a[p].l, val) : remove(a[p].r, val);
  }
  update(p);  // 最后，update。
}
/**
 * @brief Get the rank by val object
 *
 * 不会改变树的结构，也就不会调用update。
 **/
int get_rank_by_val(int p, int val) {
  if (p == 0) return 0;  // 找了，没找到。
  if (val == a[p].val)
    return a[a[p].l].size + 1;  // 排在 p 的所有左子树上节点之后
  else if (val < a[p].val)
    return get_rank_by_val(a[p].l, val);  // 在左子树中找
  else
    return get_rank_by_val(a[p].r, val)  // 在右子树中找
           + a[a[p].l].size +
           a[p].cnt;  // 右子树上所有节点都大于左子树和根节点上的值
}
int get_val_by_rank(int p, int rank) {
  if (p == 0) return INF;  // 题目保证不会出现（但愿
  if (a[a[p].l].size >= rank)
    return get_val_by_rank(a[p].l, rank);  // 直接在左子树中找
  else if (a[a[p].l].size + a[p].cnt >= rank)
    return a[p].val;  // 找到
  else                // 在右子树中找第 rank - left.size - this.cnt 个
    return get_val_by_rank(a[p].r, rank - a[a[p].l].size - a[p].cnt);
}
int get_prev(int val) {
  int ans = 1;  // a[1].val == -INF
  int p = root;
  while (p) {
    if (val != a[p].val) {
      if (a[p].val < val && a[p].val >= a[ans].val) ans = p;
      p = val < a[p].val ? a[p].l : a[p].r;
    } else {
      if (a[p].l) {
        p = a[p].l;
        while (a[p].r) p = a[p].r;
        ans = p;
      }
      p = 0;  // break;
    }
  }
  return a[ans].val;
}
int get_next(int val) {
  // 初始化 ans 为具有正无穷 val 的节点
  int ans = 2;  // a[2].val == INF
  int p = root;
  // 有三种结果：
  // 1. 没有找到val：ans 即为所求
  // 2. 找到了关键码为 val 的 p 节点，但是 p 没有右子树，ans 即为所求
  // 3. 找到了关键码为 val 的 p 节点，p 有右子树，从 p 的右子节点出发，一直向左走
  while (p) {
    if (a[p].val != val) {
      // 搜索节点
      // 看能否更新 ans
      if (a[p].val > val && a[p].val < a[ans].val) ans = p;
      p = val < a[p].val ? a[p].l : a[p].r;
    } else {
      if (a[p].r) {
        p = a[p].r;
        while (a[p].l) p = a[p].l;
        ans = p;
      }
      p = 0;
    }
  }
  return a[ans].val;
}
int main() {
  build();
  int q;
  cin >> q;
  while (q--) {
    int op, x;
    cin >> op >> x;
    switch (op) {
      case 1:
        insert(root, x);
        break;
      case 2:
        remove(root, x);
        break;
      case 3:
        cout << get_rank_by_val(root, x) - 1  // 减掉 a[1].val == -INF
             << endl;
        break;
      case 4:
        cout << get_val_by_rank(root, x + 1)  // 加上 a[1].val == -INF
             << endl;
        break;
      case 5:
        cout << get_prev(x) << endl;
        break;
      case 6:
        cout << get_next(x) << endl;
        break;
    }
  }
}
